/****************************************************
	文件：SoftSeek.cs
	作者：HuskyT
	邮箱：1005240602@qq.com
	日期：2020/5/17 18:31:16
	功能：平滑的Seek行为
*****************************************************/

using UnityEngine;

namespace AIBehavior
{
    public class SoftSeek : Decorator
    {
        private Vector3 mCurrentVelocity;
        /// <summary>
        /// 期望方向的速度
        /// </summary>
        private Vector3 mDesiredVelocity;
        /// <summary>
        /// 期望方向
        /// </summary>
        private Vector3 mDesiredDir;
        /// <summary>
        /// 引导向期望速度方向的引导力
        /// </summary>
        private Vector3 mSteerForce;
        /// <summary>
        /// 期望距离（距离目标点的距离）
        /// </summary>
        private float mDesiredDis;

        public SoftSeek(AIData data) : base(data) { }

        public override void Init(AIData data)
        {
            mCurrentVelocity = new Vector3(1 * mData.MaxVelocity, 0, 0);  //初始速度
        }

        protected override void DoSelf()
        {
            mDesiredDir = GameRoot.Instance.Pos.Value - mData.SelfTrans.position;  //期望方向：指向鼠标点击方向
            mDesiredDis = mDesiredDir.magnitude;  //期望距离（距离目标点的距离）
            if (mDesiredDis < Consts.MIN_ERROR_DELTA) return;

            if (mDesiredDis <= mData.DecelerateRadius)  //减速
            {
                mDesiredVelocity = Vector3.Normalize(GameRoot.Instance.Pos.Value - mData.SelfTrans.position) * mData.MaxVelocity * mDesiredDis / mData.DecelerateRadius;  //到达目标点后速度为零
            }
            else  //正常移动
            {
                mDesiredVelocity = Vector3.Normalize(GameRoot.Instance.Pos.Value - mData.SelfTrans.position) * mData.MaxVelocity;
            }
            mSteerForce = Vector3.ClampMagnitude(mDesiredVelocity - mCurrentVelocity, mData.MaxForce_Steer);  //引导力：由当前运动方向引导向期望方向
            mSteerForce /= mData.Mass;  //引导力=>加速度
            mCurrentVelocity = Vector3.ClampMagnitude(mCurrentVelocity + mSteerForce, mData.MaxVelocity);  //更新当前速度：受引导力影响后的速度
            mData.SelfTrans.position += mCurrentVelocity * Time.fixedDeltaTime;  //更新位置

            mData.CurrentVelocity = mCurrentVelocity;
        }
    }
}